﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AMS.DD35.DbLoader;
using AMS.Core.Data;
using AMS.Core.WinForms;
using AMS.DD35.DbLoader.Models;
using AMS.Core.Controllers;
using AMS.Core.WinForms;
using AMS.Core.Validation;
using AMS.DD35.DbLoader.Views;
using AMS.DD35.DbLoader.Controllers;
using AMS.DD35.DbLoader.Models;

namespace AMS.DD35.DbLoader.Controllers
{
    internal class MasterController : IRegisterController, ILoginController // other services
    {
        private MasterModel _model;
        private LoginDialog _loginForm;
        private DbLoaderStartForm _mainForm;

        // Sub-Controller

        private string _userName;

        #region Events (Observer)
        public event EventHandler RegistrationSucceeded
        {
            add { _model.RegistrationSucceeded += value; }
            remove { _model.RegistrationSucceeded -= value; }
        }

        public event EventHandler RegistrationFailed
        {
            add { _model.RegistrationFailed += value; }
            remove { _model.RegistrationFailed -= value; }
        }

        public event EventHandler LoginSucceeded
        {
            add { _model.LoginSucceeded += value; }
            remove { _model.LoginSucceeded -= value; }
        }

        public event EventHandler LoginFailed
        {
            add { _model.LoginFailed += value; }
            remove { _model.LoginFailed -= value; }
        }

        public event EventHandler LogoutSucceeded
        {
            add { _model.LogoutSucceeded += value; }
            remove { _model.LogoutSucceeded -= value; }
        }
        #endregion

        public MasterController()
        {
            _model = new MasterModel();
            _loginForm = new LoginDialog(this);     // move to LoginController?
            _mainForm = new DbLoaderStartForm(this);

        }

        public void ExecuteProgram()
        {
            _loginForm.ShowDialog();
            if (_loginForm.DialogResult == DialogResult.OK)
            {
                _mainForm.ShowDialog();
            }
        }

        public void Logout()
        {
            _model.Logout();
        }

        #region LoginDialog Methods
        public void AttemptLogin(string userName, string password)
        {
            // validate username and password for feasibility (probably over-engineering this...)
            if (!PasswordValidator.GetSingleInstance().ValidatePassword(password) ||
                !PasswordValidator.GetSingleInstance().ValidatePassword(userName))
            {
                MessageBox.Show("Invalid username or password!");
            }
            else
            {
                _model.Login(userName, password);
                _userName = userName;
            }
        }

        public void OpenRegisterDialog()
        {
            RegisterDialog register = new RegisterDialog(this);
            register.ShowDialog();
        }

        public void Quit()
        {
            _loginForm.Close();
        }
        #endregion

        #region RegisterDialog Methods
        public void AttemptRegister(string username,
            string password,
            string password2,
            string firstName,
            string lastName,
            string email)
        {
            // validate the two passwords are the identical
            if (password != password2)
            {
                MessageBox.Show("Passwords do not match!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            string message = "";
            if (!RegistrationDataValidator.ValidatePassword(password))
                message += "\tPassword\n";
            if (!RegistrationDataValidator.ValidateUserName(username))
                message += "\tUsername\n";
            if (!RegistrationDataValidator.ValidateEmail(email))
                message += "\tEmail Address\n";

            if (message != "")
            {
                message = "The following entries are invalid:\n" + message;
                MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            else
            {
                _model.Register(username, password, email);
            }
        }
        #endregion

        // note: lots of tight coupling follows; candidates for DI or IoCC

        // duplicating code (this and any Controller that spawns windows)
        // TODO: consider a SpawnerBase and I_Spawner interfaces

        internal void BrowseClasses()
        {
            // let ClassController handle class browsing
            IClassController classController = new ClassController();
            classController.Execute();
        }

        internal void BrowseFeats()
        {
            FeatController featController = new FeatController();
            featController.Execute();
        }

        internal void SpawnSkillsEditor()
        {
            SkillController skillController = new SkillController();
            skillController.Execute();
        }
    }
}
